#if !defined( FUNCTION_ADAPTORS_H_INCLUDED )
#define FUNCTION_ADAPTORS_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <functional>

/////////////////////////////////////////////////////////////////////////////
// t_void_binder_1st

template < typename t_binary_fun >
class t_void_binder_1st : public std::unary_function< typename t_binary_fun::second_argument_type, void >
{
public:
	// Constructor
	t_void_binder_1st( t_binary_fun binary_fun, typename t_binary_fun::first_argument_type const & first_arg )
		:	m_binary_fun( binary_fun ),
			m_first_arg( first_arg )
	{
	}

	// Operator
	void operator()( argument_type const & second_arg ) const;

private:
	// Data members
	t_binary_fun								m_binary_fun;
	typename t_binary_fun::first_argument_type	m_first_arg;
};

template < typename t_binary_fun >
inline void t_void_binder_1st< t_binary_fun >::operator()( argument_type const & second_arg ) const
{
	m_binary_fun( m_first_arg, second_arg );
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_void_binder_1st

template < typename t_binary_fun, typename t_second_arg >
inline t_void_binder_1st< t_binary_fun > void_bind_1st( t_binary_fun binary_fun, t_second_arg const & first_arg )
{
	return t_void_binder_1st< t_binary_fun >( binary_fun, first_arg );
}

/////////////////////////////////////////////////////////////////////////////
// t_void_binder_2nd

template < typename t_binary_fun >
class t_void_binder_2nd : public std::unary_function< typename t_binary_fun::first_argument_type, void >
{
public:
	// Constructor
	t_void_binder_2nd( t_binary_fun binary_fun, typename t_binary_fun::second_argument_type const & second_arg )
		:	m_binary_fun( binary_fun ),
			m_second_arg( second_arg )
	{
	}

	// Operator
	void operator()( argument_type const & first_arg ) const;

private:
	// Data members
	t_binary_fun								m_binary_fun;
	typename t_binary_fun::second_argument_type	m_second_arg;
};

template < typename t_binary_fun >
inline void t_void_binder_2nd< t_binary_fun >::operator()( argument_type const & first_arg ) const
{
	m_binary_fun( first_arg, m_second_arg );
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_void_binder_2nd

template < typename t_binary_fun, typename t_second_arg >
inline t_void_binder_2nd< t_binary_fun > void_bind_2nd( t_binary_fun binary_fun, t_second_arg const & second_arg )
{
	return t_void_binder_2nd< t_binary_fun >( binary_fun, second_arg );
}

/////////////////////////////////////////////////////////////////////////////
// t_pointer_to_void_unary_function

template < typename t_arg >
class t_pointer_to_void_unary_function : public std::unary_function< t_arg, void >
{
public:
	// Constructor
	t_pointer_to_void_unary_function( void ( * fun_ptr )( t_arg ) ) : m_fun_ptr( fun_ptr ){}

	// Operator
	void operator()( t_arg arg ) const { m_fun_ptr( arg ); }

private:
	// Data members
	void ( * m_fun_ptr )( t_arg );
};

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_pointer_to_void_unary_function

template < typename t_arg >
inline t_pointer_to_void_unary_function< t_arg > ptr_void_fun( void ( * fun_ptr )( t_arg ) )
{
	return t_pointer_to_void_unary_function< t_arg >( fun_ptr );
}

/////////////////////////////////////////////////////////////////////////////
// t_pointer_to_void_binary_function

template < typename t_arg1, typename t_arg2 >
class t_pointer_to_void_binary_function : public std::binary_function< t_arg1, t_arg2, void >
{
public:
	// Constructor
	t_pointer_to_void_binary_function( void ( * fun_ptr )( t_arg1, t_arg2 ) ) : m_fun_ptr( fun_ptr ){}

	// Operator
	void operator()( t_arg1 arg1, t_arg2 arg2 ) const { m_fun_ptr( arg1, arg2 ); }

private:
	// Data members
	void ( * m_fun_ptr )( t_arg1, t_arg2 );
};

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_pointer_to_void_binary_function

template < typename t_arg1, typename t_arg2 >
inline t_pointer_to_void_binary_function< t_arg1, t_arg2 > ptr_void_fun( void ( * fun_ptr )( t_arg1, t_arg2 ) )
{
	return t_pointer_to_void_binary_function< t_arg1, t_arg2 >( fun_ptr );
}

/////////////////////////////////////////////////////////////////////////////
// t_void_mem_fun

template < typename t_obj >
class t_void_mem_fun : public std::unary_function< t_obj *, void >
{
public:
	// Constructor
	t_void_mem_fun( void ( t_obj::* fun_ptr )() );

	// Operator
	void operator()( t_obj * obj_ptr ) const;

private:
	// Data members
	void ( t_obj::* m_fun_ptr )();
};

template < typename t_obj >
inline t_void_mem_fun< t_obj >::t_void_mem_fun( void ( t_obj::* fun_ptr )() )
	:	m_fun_ptr( fun_ptr )
{
}

template < typename t_obj >
inline void t_void_mem_fun< t_obj >::operator()( t_obj * obj_ptr ) const
{
	( obj_ptr->*m_fun_ptr )();
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_void_mem_fun

template < typename t_obj >
inline t_void_mem_fun< t_obj > void_mem_fun( void ( t_obj::* fun_ptr )() )
{
	return t_void_mem_fun< t_obj >( fun_ptr );
}

/////////////////////////////////////////////////////////////////////////////
// t_const_void_mem_fun

template < typename t_obj >
class t_const_void_mem_fun : public std::unary_function< t_obj const *, void >
{
public:
	// Constructor
	t_const_void_mem_fun( void ( t_obj::* fun_ptr )() const );

	// Operator
	void operator()( t_obj const * obj_ptr ) const;

private:
	// Data members
	void ( t_obj::* m_fun_ptr )() const;
};

template < typename t_obj >
inline t_const_void_mem_fun< t_obj >::t_const_void_mem_fun( void ( t_obj::* fun_ptr )() const )
	:	m_fun_ptr( fun_ptr )
{
}

template < typename t_obj >
inline void t_const_void_mem_fun< t_obj >::operator()( t_obj const * obj_ptr ) const
{
	( obj_ptr->*m_fun_ptr )();
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_const_void_mem_fun

template < typename t_obj >
inline t_const_void_mem_fun< t_obj > void_mem_fun( void ( t_obj::* fun_ptr )() const )
{
	return t_const_void_mem_fun< t_obj >( fun_ptr );
}

/////////////////////////////////////////////////////////////////////////////
// t_void_mem_fun1

template < typename t_obj, typename t_arg >
class t_void_mem_fun1 : public std::binary_function< t_obj *, t_arg, void >
{
public:
	// Constructor
	t_void_mem_fun1( void ( t_obj::* fun_ptr )( t_arg ) );

	// Operator
	void operator()( t_obj * obj_ptr, t_arg arg ) const;

private:
	// Data members
	void ( t_obj::* m_fun_ptr )( t_arg );
};

template < typename t_obj, typename t_arg >
inline t_void_mem_fun1< t_obj, t_arg >::t_void_mem_fun1( void ( t_obj::* fun_ptr )( t_arg ) )
	:	m_fun_ptr( fun_ptr )
{
}

template < typename t_obj, typename t_arg >
inline void t_void_mem_fun1< t_obj, t_arg >::operator()( t_obj * obj_ptr, t_arg arg ) const
{
	( obj_ptr->*m_fun_ptr )( arg );
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_void_mem_fun1

template < typename t_obj, typename t_arg >
inline t_void_mem_fun1< t_obj, t_arg > void_mem_fun( void ( t_obj::* fun_ptr )( t_arg ) )
{
	return t_void_mem_fun1< t_obj, t_arg >( fun_ptr );
}

/////////////////////////////////////////////////////////////////////////////
// t_const_void_mem_fun1

template < typename t_obj, typename t_arg >
class t_const_void_mem_fun1 : public std::binary_function< t_obj const *, t_arg, void >
{
public:
	// Constructor
	t_const_void_mem_fun1( void ( t_obj::* fun_ptr )( t_arg ) const );

	// Operator
	void operator()( t_obj const * obj_ptr, t_arg arg ) const;

private:
	// Data members
	void ( t_obj::* m_fun_ptr )( t_arg ) const;
};

template < typename t_obj, typename t_arg >
inline t_const_void_mem_fun1< t_obj, t_arg >::t_const_void_mem_fun1( void ( t_obj::* fun_ptr )( t_arg ) const )
	:	m_fun_ptr( fun_ptr )
{
}

template < typename t_obj, typename t_arg >
inline void t_const_void_mem_fun1< t_obj, t_arg >::operator()( t_obj const * obj_ptr, t_arg arg ) const
{
	( obj_ptr->*m_fun_ptr )( arg );
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_const_void_mem_fun1

template < typename t_obj, typename t_arg >
inline t_const_void_mem_fun1< t_obj, t_arg > void_mem_fun( void ( t_obj::* fun_ptr )( t_arg ) const )
{
	return t_const_void_mem_fun1< t_obj, t_arg >( fun_ptr );
}

/////////////////////////////////////////////////////////////////////////////
// t_void_mem_fun_ref

template < typename t_obj >
class t_void_mem_fun_ref : public std::unary_function< t_obj, void >
{
public:
	// Constructor
	t_void_mem_fun_ref( void ( t_obj::* fun_ptr )() );

	// Operator
	void operator()( t_obj & obj ) const;

private:
	// Data members
	void ( t_obj::* m_fun_ptr )();
};

template < typename t_obj >
inline t_void_mem_fun_ref< t_obj >::t_void_mem_fun_ref( void ( t_obj::* fun_ptr )() )
	:	m_fun_ptr( fun_ptr )
{
}

template < typename t_obj >
inline void t_void_mem_fun_ref< t_obj >::operator()( t_obj & obj ) const
{
	( obj.*m_fun_ptr )();
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_void_mem_fun_ref

template < typename t_obj >
inline t_void_mem_fun_ref< t_obj > void_mem_fun_ref( void ( t_obj::* fun_ptr )() )
{
	return t_void_mem_fun_ref< t_obj >( fun_ptr );
}

/////////////////////////////////////////////////////////////////////////////
// t_const_void_mem_fun_ref

template < typename t_obj >
class t_const_void_mem_fun_ref : public std::unary_function< t_obj, void >
{
public:
	// Constructor
	t_const_void_mem_fun_ref( void ( t_obj::* fun_ptr )() const );

	// Operator
	void operator()( t_obj const & obj ) const;

private:
	// Data members
	void ( t_obj::* m_fun_ptr )() const;
};

template < typename t_obj >
inline t_const_void_mem_fun_ref< t_obj >::t_const_void_mem_fun_ref( void ( t_obj::* fun_ptr )() const )
	:	m_fun_ptr( fun_ptr )
{
}

template < typename t_obj >
inline void t_const_void_mem_fun_ref< t_obj >::operator()( t_obj const & obj ) const
{
	( obj.*m_fun_ptr )();
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_const_void_mem_fun_ref

template < typename t_obj >
inline t_const_void_mem_fun_ref< t_obj > void_mem_fun_ref( void ( t_obj::* fun_ptr )() const )
{
	return t_const_void_mem_fun_ref< t_obj >( fun_ptr );
}

/////////////////////////////////////////////////////////////////////////////
// t_void_mem_fun1_ref

template < typename t_obj, typename t_arg >
class t_void_mem_fun1_ref : public std::binary_function< t_obj, t_arg, void >
{
public:
	// Constructor
	t_void_mem_fun1_ref( void ( t_obj::* fun_ptr )( t_arg ) );

	// Operator
	void operator()( t_obj & obj, t_arg arg ) const;

private:
	// Data members
	void ( t_obj::* m_fun_ptr )( t_arg );
};

template < typename t_obj, typename t_arg >
inline t_void_mem_fun1_ref< t_obj, t_arg >::t_void_mem_fun1_ref( void ( t_obj::* fun_ptr )( t_arg ) )
	:	m_fun_ptr( fun_ptr )
{
}

template < typename t_obj, typename t_arg >
inline void t_void_mem_fun1_ref< t_obj, t_arg >::operator()( t_obj & obj, t_arg arg ) const
{
	( obj_ptr.*m_fun_ptr )( arg );
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_void_mem_fun1_ref

template < typename t_obj, typename t_arg >
inline t_void_mem_fun1_ref< t_obj, t_arg > void_mem_fun_ref( void ( t_obj::* fun_ptr )( t_arg ) )
{
	return t_void_mem_fun1_ref< t_obj, t_arg >( fun_ptr );
}

/////////////////////////////////////////////////////////////////////////////
// t_const_void_mem_fun1_ref

template < typename t_obj, typename t_arg >
class t_const_void_mem_fun1_ref : public std::binary_function< t_obj, t_arg, void >
{
public:
	// Constructor
	t_const_void_mem_fun1_ref( void ( t_obj::* fun_ptr )( t_arg ) const );

	// Operator
	void operator()( t_obj const & obj, t_arg arg ) const;

private:
	// Data members
	void ( t_obj::* m_fun_ptr )( t_arg ) const;
};

template < typename t_obj, typename t_arg >
inline t_const_void_mem_fun1_ref< t_obj, t_arg >::t_const_void_mem_fun1_ref( void ( t_obj::* fun_ptr )( t_arg ) const )
	:	m_fun_ptr( fun_ptr )
{
}

template < typename t_obj, typename t_arg >
inline void t_const_void_mem_fun1_ref< t_obj, t_arg >::operator()( t_obj const & obj, t_arg arg ) const
{
	( obj_ptr.*m_fun_ptr )( arg );
}

/////////////////////////////////////////////////////////////////////////////
// Helper function for creating t_const_void_mem_fun1_ref

template < typename t_obj, typename t_arg >
inline t_const_void_mem_fun1_ref< t_obj, t_arg > void_mem_fun_ref( void ( t_obj::* fun_ptr )( t_arg ) const )
{
	return t_const_void_mem_fun1_ref< t_obj, t_arg >( fun_ptr );
}

#endif // !defined( FUNCTION_ADAPTORS_H_INCLUDED
